#include <stdio.h>

// ============= 第一课：基础指针概念 =============
// 理解内存地址、指针声明和初始化

int main(void) {
    printf("=== C语言指针学习 - 第一课：基础概念 ===\n\n");
    
    // 1. 理解变量和内存地址
    int age = 25;
    char grade = 'A';
    float score = 95.5f;
    
    printf("1. 变量和内存地址的概念：\n");
    printf("   age = %d, 存储在地址: %p\n", age, (void*)&age);
    printf("   grade = %c, 存储在地址: %p\n", grade, (void*)&grade);
    printf("   score = %.1f, 存储在地址: %p\n", score, (void*)&score);
    printf("   注意：& 是取地址操作符\n\n");
    
    // 2. 指针的声明和初始化
    printf("2. 指针的声明和初始化：\n");
    int *ptr_age = &age;        // 声明一个指向int的指针，并初始化为age的地址
    char *ptr_grade = &grade;   // 声明一个指向char的指针
    float *ptr_score = &score;  // 声明一个指向float的指针
    
    printf("   int *ptr_age = &age;    // 指针ptr_age指向age\n");
    printf("   ptr_age 的值（即age的地址）: %p\n", (void*)ptr_age);
    printf("   ptr_age 自身的地址: %p\n", (void*)&ptr_age);
    printf("\n");
    
    // 3. 指针的解引用（通过指针访问值）
    printf("3. 指针的解引用（* 操作符）：\n");
    printf("   *ptr_age = %d    // 通过指针访问age的值\n", *ptr_age);
    printf("   *ptr_grade = %c  // 通过指针访问grade的值\n", *ptr_grade);
    printf("   *ptr_score = %.1f // 通过指针访问score的值\n", *ptr_score);
    printf("\n");
    
    // 4. 通过指针修改值
    printf("4. 通过指针修改原变量的值：\n");
    printf("   修改前: age = %d\n", age);
    *ptr_age = 30;  // 通过指针修改age的值
    printf("   执行 *ptr_age = 30; 后\n");
    printf("   修改后: age = %d\n", age);
    printf("   说明：指针可以间接修改原变量的值\n\n");
    
    // 5. 指针的大小
    printf("5. 指针的大小（在64位系统上通常是8字节）：\n");
    printf("   sizeof(ptr_age) = %lu 字节\n", sizeof(ptr_age));
    printf("   sizeof(ptr_grade) = %lu 字节\n", sizeof(ptr_grade));
    printf("   sizeof(ptr_score) = %lu 字节\n", sizeof(ptr_score));
    printf("   注意：所有指针的大小都相同，与指向的数据类型无关\n\n");
    
    // 6. 空指针的概念
    printf("6. 空指针（NULL指针）：\n");
    int *null_ptr = NULL;
    printf("   int *null_ptr = NULL;  // 空指针，不指向任何有效地址\n");
    printf("   null_ptr 的值: %p\n", (void*)null_ptr);
    printf("   警告：永远不要解引用空指针！\n\n");
    
    printf("=== 第一课总结 ===\n");
    printf("1. 指针是存储内存地址的变量\n");
    printf("2. & 操作符用于获取变量的地址\n");
    printf("3. * 操作符用于声明指针和解引用指针\n");
    printf("4. 通过指针可以间接访问和修改变量的值\n");
    printf("5. 所有指针的大小都相同\n");
    printf("6. NULL指针不指向任何有效地址\n");
    
    return 0;
}
